package com.passkeeper.aspect;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.regex.Pattern;

import net.sf.json.JSONObject;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.passkeeper.aspect.dao.LogMapper;
import com.passkeeper.aspect.model.LogWithBLOBs;



/**
 * DAO层AOP拦截器，实现记录用户操作过的所有方法和参数，并实现DAO层缓存
 * 
 * @author Administrator
 * 
 */
@Aspect
@Component
public class DaoAspect {

	//@Autowired
	//@Qualifier("CacheService")
	//private CacheService memcache;

	@Autowired
	private LogMapper SysLogDAO;

	@Around("execution(* com.passkeeper.jdbc.dao.*.*(..))")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		// 获取请求事务ID信息
		// ThreadId threadId = new ThreadBean().getThreadId();
		ThreadMXBean threadId = ManagementFactory.getThreadMXBean();
		// 调用方法名称
		String methodName = joinPoint.getSignature().getName();
		// 调用参数
		Object[] args = joinPoint.getArgs();
		//System.out.println("args:"+joinPoint.getArgs());
		//System.out.println("class:"+joinPoint.getClass());
		//System.out.println("signature:"+joinPoint.getSignature().getDeclaringTypeName());
		Object object = null;
		
		LogWithBLOBs sysLogDetail = new LogWithBLOBs();

		// 数据库更新操作日志
		if (Pattern.matches("(save|insert|add|delete|remove|del|update)[\\S]*",
				methodName)) {
			if (threadId != null) {
				// 获取执行请求事务ID
				//String transactionalId = threadId.getTransactionalId();
				// 获取执行请求用户ID
				//String userId = threadId.getUserId();
				//sysLogDetail.setXh(transactionalId);
				//sysLogDetail.setUserId(userId);
				//sysLogDetail.setMethod(methodName);
				JSONObject msg = new JSONObject();
				// 处理参数
				for (Object temp : args) {
					// 获取参数类型,不同参数类型数据处理不一样
					Class<? extends Object> paramClazz = temp.getClass();
					String classType = paramClazz.getName();
					if (classType.equals("java.lang.String")) {
						msg.put("key", temp);
					} else if (classType.equals("java.util.HashMap")) {
						msg.putAll((HashMap<?, ?>) temp);
					} else if (classType.startsWith("com.hordecraft.jdbc")) {
						try {
							sysLogDetail.setDomain(classType);
							Field[] f = paramClazz.getDeclaredFields();
							for (Field field : f) {
								String fieldName = field.getName();
								field.setAccessible(true);
								msg.put(fieldName, field.get(temp));
							}
						} catch (SecurityException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						}
					}
				}
				sysLogDetail.setChanged(msg.toString());
			}
			// 执行数据库操作
			object = joinPoint.proceed();
			
			/*更新完了，再取一次值*/
			if (threadId != null) {
				JSONObject msg = new JSONObject();
				// 处理参数
				//args = joinPoint.getArgs();
				args[0] = object;
				for (Object temp : args) {
					// 获取参数类型,不同参数类型数据处理不一样
					Class<? extends Object> paramClazz = temp.getClass();
					String classType = paramClazz.getName();
					if (classType.equals("java.lang.String")) {
						msg.put("key", temp);
					} else if (classType.equals("java.util.HashMap")) {
						msg.putAll((HashMap<?, ?>) temp);
					} else if (classType.startsWith("com.passkeeper.jdbc")) {
						try {
							Field[] f = paramClazz.getDeclaredFields();
							for (Field field : f) {
								String fieldName = field.getName();
								field.setAccessible(true);
								msg.put(fieldName, field.get(temp));
							}
						} catch (SecurityException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						}
					}
				}
				sysLogDetail.setChanged(msg.toString());
			}
			sysLogDetail.setCreatedate(new Date());
			SysLogDAO.insertSelective(sysLogDetail);

			// 数据库查询缓存
		} else if (Pattern.matches("(query|load|get|select|read)[\\S]*",
				methodName)) {
			/**Memcache部分，不必须，而且不会弄，先屏蔽，容后研竄
			// DAO层缓存注解
			MemCacheKey cacheKey = new MemCacheKey();
			// 获取cache注解属性
			Cache cache = null;
			// 获取请求方法
			Class<?> cls = joinPoint.getTarget().getClass();
			// 获取class中的所有方法
			Method[] methods = cls.getMethods();
			for (Method m : methods) {
				// 获取执行方法前的注解信息。
				if (m.getName().equals(methodName)) {
					cache = m.getAnnotation(Cache.class);
					break;
				}
			}

			if (cache != null) {
				// 获取memcacheKey,并进行MD5加密
				cacheKey = memcacheKey(cache, args);
				// 判断缓存服务器是否存在该可以值
				if (memcache.exist(cacheKey.getMemcacheKey())) {
					object = memcache.get(cacheKey.getMemcacheKey());
				} else {
					// 执行数据库操作
					object = joinPoint.proceed();
					// 将数据存放进缓存
					if (cacheKey.getMemcacheKey() != null) {
						memcache.put(cacheKey.getMemcacheKey(),
								object == null ? "" : object,
								new Date(cacheKey.getTime()));
					}
				}
			} else {
				// 执行数据库操作
				object = joinPoint.proceed();
			}
			*/
		} else {
			// 执行数据库操作
			object = joinPoint.proceed();
		}

		return object;

	}
	
	@AfterReturning("execution(* com.hordercraft.jdbc.dao.*.*(..))")
	public Object after(JoinPoint joinPoint) throws Throwable {
		// 获取请求事务ID信息
		// ThreadId threadId = new ThreadBean().getThreadId();
		ThreadMXBean threadId = ManagementFactory.getThreadMXBean();
		// 调用方法名称
		String methodName = joinPoint.getSignature().getName();
		// 调用参数
		Object[] args = joinPoint.getArgs();
		//System.out.println("args:"+joinPoint.getArgs());
		//System.out.println("class:"+joinPoint.getClass());
		//System.out.println("signature:"+joinPoint.getSignature().getDeclaringTypeName());
		Object object = null;

		// 数据库更新操作日志
		if (Pattern.matches("(save|insert|add|delete|remove|del|update)[\\S]*",
				methodName)) {
			if (threadId != null) {
				// 获取执行请求事务ID
				//String transactionalId = threadId.getTransactionalId();
				// 获取执行请求用户ID
				//String userId = threadId.getUserId();
				LogWithBLOBs sysLogDetail = new LogWithBLOBs();
				//sysLogDetail.setXh(transactionalId);
				//sysLogDetail.setUserId(userId);
				//sysLogDetail.setMethod(methodName);
				JSONObject msg = new JSONObject();
				// 处理参数
				for (Object temp : args) {
					// 获取参数类型,不同参数类型数据处理不一样
					Class<? extends Object> paramClazz = temp.getClass();
					String classType = paramClazz.getName();
					if (classType.equals("java.lang.String")) {
						msg.put("key", temp);
					} else if (classType.equals("java.util.HashMap")) {
						msg.putAll((HashMap<?, ?>) temp);
					} else if (classType.startsWith("com.hordecraft.jdbc")) {
						try {
							Field[] f = paramClazz.getDeclaredFields();
							for (Field field : f) {
								String fieldName = field.getName();
								field.setAccessible(true);
								msg.put(fieldName, field.get(temp));
							}
						} catch (SecurityException e) {
							e.printStackTrace();
						} catch (IllegalArgumentException e) {
							e.printStackTrace();
						}
					}
				}
				sysLogDetail.setChanged(msg.toString());
				// 记录DAO数据库操作日志
				SysLogDAO.insertSelective(sysLogDetail);
			}
			// 执行数据库操作
			//object = joinPoint.proceed();

			// 数据库查询缓存
		} else if (Pattern.matches("(query|load|get|select|read)[\\S]*",
				methodName)) {
			/**Memcache部分，不必须，而且不会弄，先屏蔽，容后研竄
			// DAO层缓存注解
			MemCacheKey cacheKey = new MemCacheKey();
			// 获取cache注解属性
			Cache cache = null;
			// 获取请求方法
			Class<?> cls = joinPoint.getTarget().getClass();
			// 获取class中的所有方法
			Method[] methods = cls.getMethods();
			for (Method m : methods) {
				// 获取执行方法前的注解信息。
				if (m.getName().equals(methodName)) {
					cache = m.getAnnotation(Cache.class);
					break;
				}
			}

			if (cache != null) {
				// 获取memcacheKey,并进行MD5加密
				cacheKey = memcacheKey(cache, args);
				// 判断缓存服务器是否存在该可以值
				if (memcache.exist(cacheKey.getMemcacheKey())) {
					object = memcache.get(cacheKey.getMemcacheKey());
				} else {
					// 执行数据库操作
					object = joinPoint.proceed();
					// 将数据存放进缓存
					if (cacheKey.getMemcacheKey() != null) {
						memcache.put(cacheKey.getMemcacheKey(),
								object == null ? "" : object,
								new Date(cacheKey.getTime()));
					}
				}
			} else {
				// 执行数据库操作
				object = joinPoint.proceed();
			}
			*/
		} else {
			// 执行数据库操作
			//object = joinPoint.proceed();
		}

		return object;

	}

	
}